package com.cosc716.simulator;

/**
 * @author davidmessing
 *
 */
public class SimulationContext {
	
	public final static int MIN_TIME_INTERVALS = 0;		// timeIntervals cannot be negative
	public final static int MAX_TIME_INTERVALS = 525949; 	// = one year when timeInterval is specified as minute
	
	private int timeIntervals;
	private int currentTime = 0;
	private RunLoop runLoop;
	private DataSource datasource;
	
	public SimulationContext() {
		
		// initialize ivars
		this.timeIntervals = 0;
		this.runLoop = new RunLoop();
	}
	
	public int getTimeIntervals() {
		return timeIntervals;
	}

	public void setTimeIntervals(int timeIntervals) {
		if ( timeIntervals > MAX_TIME_INTERVALS ) {
			this.timeIntervals = MAX_TIME_INTERVALS;
		}
		else if( timeIntervals < MIN_TIME_INTERVALS ) {
			this.timeIntervals = MIN_TIME_INTERVALS;
		}
		else {
			this.timeIntervals = timeIntervals;
		}
	}
	
	public DataSource getDatasource() {
		return datasource;
	}

	public void setDatasource(DataSource datasource) {
		this.datasource = datasource;
	}
	
	public void setPatronEatTime(int timeInterval) {
		this.datasource.setPatronEatTime(timeInterval);
	}
	
	public void setPrepCapacity(int capacity) {
		this.datasource.setPreparationCapacity(capacity);
	}

	public void addCommand(RunLoopCommand command) {
		try {
			this.runLoop.addCommand(command);
		} catch (RunLoopException e) {
			System.err.println("RunLoopException: " + e.getMessage());
		}
	}

	public void run() {
		
		if( null == runLoop ) {
			// better to bail out here, than to potentially call run() 525949 times
			return;
		}
		
		if ( null == datasource) {
			return;
		}
		
		// run the simulation
		for (int i = 0; i < timeIntervals; i++) {
			this.currentTime = i;
			// the runLoop will execute every command once per simulation time interval 
			this.runLoop.run(i);
		}
	}
	
	public void run(int stepSize) {
		if( null == runLoop ) {
			// better to bail out here, than to potentially call run() 525949 times
			return;
		}
		
		if ( null == datasource) {
			return;
		}
		
		int limit = currentTime + stepSize;
		for (int i = currentTime; i < limit; i++) {
			this.currentTime = i;
			this.runLoop.run(i);
		}
	}
}
